import numpy as np
import scipy.special as sc
from chaco.api import *
from traits.api import *
from traitsui.api import *
from enable.api import ComponentEditor
class MonoInteface(HasTraits):
    incidentAngle = np.arange(91)
    costheta = np.cos(incidentAngle * np.pi / 180)
    sintheta = np.sin(incidentAngle * np.pi / 180)
    data = Property(Array, observe=['epsilonReal', 'epsilonImage', 'muReal','muImage',])#换成Map就不行
    huanjing = Enum('沙漠','草原','树林')
    kongqi = Float(4.0)
    fre = Range(low=0, high=100., value=4.0)
    epsilonReal = Range(low=0, high=10.0, value=4.0)
    epsilonImage = Range(low=0, high=10.0, value=0)
    muReal = Range(low=0, high=10.0, value=2.0)
    muImage = Range(low=0, high=10.0, value=0)
    thick = Range(low=1, high=10.0, value=3)
    plot = Instance(Plot)
    def _plot_default(self):
        plot = Plot(ArrayPlotData(
            incidentAngle=self.incidentAngle,
            reflectionTE=self.data['reflectionTE'],
            reflectionTM=self.data['reflectionTM'],
            transmissionTE=self.data['transmissionTE'],
            transmissionTM=self.data['transmissionTM'],
                                      ))
        plot.title = 'Reflection and Transmission'
        plot.x_axis.title = "Incident Angle / deg"
        plot.y_axis.title = "Reflection and Transmission"
        plot.range2d.set_bounds((0,0), (90,2))
        plot.plot(("incidentAngle", "reflectionTE"),name='reflection TE',color=palette11[0])
        plot.plot(("incidentAngle", "reflectionTM"),name='reflection TM',color=palette11[1])
        plot.plot(("incidentAngle", "transmissionTE"),name='transmission TE',color=palette11[2])
        plot.plot(("incidentAngle", "transmissionTM"),name='transmission TM',color=palette11[3])
        # plot.plot(("incidentAngle", "transmissionTM"),name='transmission TM',color=palette11[4])
        # plot.plot(("incidentAngle", "transmissionTM"),name='transmission TM2',color=palette11[5])
        # plot.plot(("incidentAngle", "transmissionTM"),name='transmission TM3',color=palette11[6])
        # plot.plot(("incidentAngle", "transmissionTM"),name='transmission TM4',color=palette11[7])
        legend = Legend()
        legend.plots = plot.plots
        plot.overlays.append(legend)
        return plot
    def _get_data(self):
        data={}
        epsilon=self.epsilonReal-1j*self.epsilonImage
        mu=self.muReal-1j*self.muImage
        k=np.sqrt(epsilon * mu - self.sintheta ** 2)
        z=self.costheta/k*mu
        data['reflectionTE']=np.abs((z-1)/(z+1))
        data['transmissionTE']=np.abs(2*z/(z+1))
        z=self.costheta/k*epsilon
        data['reflectionTM']=np.abs((z-1)/(z+1))
        data['transmissionTM']=np.abs(2*z/(z+1))
        return data
    @observe("data")
    def _update_plot(self, event):
        self.plot.data.update_data(
            reflectionTE=self.data['reflectionTE'],
            reflectionTM=self.data['reflectionTM'],
            transmissionTE=self.data['transmissionTE'],
            transmissionTM=self.data['transmissionTM'],
        )
    traits_view = View(
        Group(
            UItem(
                "plot",
                editor=ComponentEditor(),
                resizable=True
            )),
            Item('huanjing',label='环境',style='custom'),
            Item('kongqi',label='空气'),
            Item('fre',label='频率(GHz)'),
            Item('epsilonReal',label='介电常数实部'),
            Item('epsilonImage',label='介电常数虚部'),
            Item('muReal',label='磁导率实部'),
            Item('muImage',label='磁导率虚部'),
            Item('thick',label='厚度/mm'),
        )
class Slab(HasTraits):
    incidentAngleRange = np.arange(0,90.5,.5)
    frequencyRange = np.arange(0,100.1,.1)
    incidentAngle = Range(low=0, high=90., value=0.)# unit deg
    frequency = Range(low=0, high=100.0, value=2.0)# unit GHz
    plotIncidentAngle = Instance(Plot)
    plotFrequency = Instance(Plot)
    epsilonReal = Range(low=0, high=10.0, value=4.0)
    epsilonImage = Range(low=0, high=10.0, value=0)
    muReal = Range(low=0, high=10.0, value=2.0)
    muImage = Range(low=0, high=10.0, value=0)
    thickness = Range(low=0, high=50.0, value=2.0)# unit mm
    class Material(HasTraits):
        epsilonReal = Range(low=0, high=10.0, value=4.0)
        epsilonImage = Range(low=0, high=10.0, value=0)
        muReal = Range(low=0, high=10.0, value=2.0)
        muImage = Range(low=0, high=10.0, value=0)
        traits_view=View(
            Item('epsilonReal',label='介电常数实部'),
            Item('epsilonImage',label='介电常数虚部'),
            Item('muReal',label='磁导率实部'),
            Item('muImage',label='磁导率虚部'),
        )
    slab=Instance(Material,())
    background=Instance(Material,())
    backgroundType=Enum('自由空间','导体','介质')
    costheta = np.cos(incidentAngleRange * np.pi / 180)
    sintheta = np.sin(incidentAngleRange * np.pi / 180)
    dataIncidentAngle = Property(Dict, observe=['epsilonReal', 'epsilonImage', 'muReal','muImage','thickness','frequency','slab.*','background.*','backgroundType',])
    dataFrequency = Property(Dict, observe=['epsilonReal', 'epsilonImage', 'muReal','muImage','thickness','incidentAngle','slab.*','background.*','backgroundType',])
    def __init__(self):
        super().__init__()
    def _plotIncidentAngle_default(self):
        plot = Plot(ArrayPlotData(
            incidentAngleRange=self.incidentAngleRange,
            reflectionTE=self.dataIncidentAngle['reflectionTE'],
            reflectionTM=self.dataIncidentAngle['reflectionTM'],
            transmissionTE=self.dataIncidentAngle['transmissionTE'],
            transmissionTM=self.dataIncidentAngle['transmissionTM'],
                                      ))
        plot.title = 'Reflection and Transmission'
        plot.x_axis.title = "Incident Angle / deg"
        plot.y_axis.title = "Reflection and Transmission"
        plot.range2d.set_bounds((0, 0), (90, 1))
        plot.plot(("incidentAngleRange", "reflectionTE"),name='Reflection TE',color=palette11[0])
        plot.plot(("incidentAngleRange", "reflectionTM"),name='Reflection TM',color=palette11[1])
        plot.plot(("incidentAngleRange", "transmissionTE"),name='Transmission TE',color=palette11[2])
        plot.plot(("incidentAngleRange", "transmissionTM"),name='Transmission TM',color=palette11[3])
        legend = Legend()
        legend.plots = plot.plots
        plot.overlays.append(legend)
        return plot
    def _plotFrequency_default(self):
        plot = Plot(ArrayPlotData(
            frequencyRange=self.frequencyRange,
            reflectionTE=self.dataFrequency['reflectionTE'],
            reflectionTM=self.dataFrequency['reflectionTM'],
            transmissionTE=self.dataFrequency['transmissionTE'],
            transmissionTM=self.dataFrequency['transmissionTM'],
                                      ))
        plot.title = 'Reflection and Transmission'
        plot.x_axis.title = "Frequency / GHz"
        plot.y_axis.title = "Reflection and Transmission"
        plot.range2d.set_bounds((0, 0), (90, 1))
        plot.plot(("frequencyRange", "reflectionTE"),name='Reflection TE',color=palette11[0])
        plot.plot(("frequencyRange", "reflectionTM"),name='Reflection TM',color=palette11[1])
        plot.plot(("frequencyRange", "transmissionTE"),name='Transmission TE',color=palette11[2])
        plot.plot(("frequencyRange", "transmissionTM"),name='Transmission TM',color=palette11[3])
        legend = Legend()
        legend.plots = plot.plots
        plot.overlays.append(legend)
        return plot
    def _get_dataIncidentAngle(self):
        epsilonSlab = self.slab.epsilonReal - 1j * self.slab.epsilonImage
        muSlab = self.slab.muReal - 1j * self.slab.muImage
        kSlab = np.sqrt(epsilonSlab * muSlab - self.sintheta ** 2)
        zSlab = self.costheta / kSlab * muSlab
        ySlab = self.costheta / kSlab * epsilonSlab
        expjkd = np.exp(-2j * np.pi * self.frequency * self.thickness / 300 * kSlab)
        exp2jkd = expjkd ** 2
        data={}
        match self.backgroundType:
            case '自由空间':
                r = (zSlab - 1) / (zSlab + 1)
                reflectionTE=(1 - exp2jkd) * r / (1 - exp2jkd * r ** 2)
                transmissionTE=(1 - r ** 2) * expjkd / (1 - exp2jkd * r ** 2)
                r = (ySlab - 1) / (ySlab + 1)
                reflectionTM=(1 - exp2jkd) * r / (1 - exp2jkd * r ** 2)
                transmissionTM=(1 - r ** 2) * expjkd / (1 - exp2jkd * r ** 2)
            case '导体':
                cosjkd = np.cos(-2j * np.pi * self.frequency * self.thickness / 300 * kSlab)
                sinjkd = np.sin(-2j * np.pi * self.frequency * self.thickness / 300 * kSlab)
                reflectionTE = (zSlab * 1j * sinjkd - cosjkd) / (zSlab * 1j * sinjkd + cosjkd)
                transmissionTE = np.zeros_like(reflectionTE)
                reflectionTM = (ySlab * cosjkd - 1j * sinjkd) / (ySlab * cosjkd + 1j * sinjkd)
                transmissionTM = np.zeros_like(reflectionTM)
            case '介质':
                epsilonBackground = self.background.epsilonReal - 1j * self.background.epsilonImage
                muBackground = self.background.muReal - 1j * self.background.muImage
                kBackground = np.sqrt(epsilonBackground * muBackground - self.sintheta ** 2)
                zBackground = kSlab/kBackground * muBackground/muSlab
                rBackground=(zBackground-1)/(zBackground+1)
                r=rBackground*exp2jkd
                zSlab*=(1+r)/(1-r)
                reflectionTE=(zSlab-1)/(zSlab+1)
                transmissionTE=(1+r)*expjkd/(1+rBackground*exp2jkd)*(1+rBackground)
                yBackground = kSlab/kBackground * epsilonBackground/epsilonSlab
                rBackground=(yBackground-1)/(yBackground+1)
                r=rBackground*exp2jkd
                ySlab*=(1+r)/(1-r)
                reflectionTM=(ySlab-1)/(ySlab+1)
                transmissionTM=(1+r)*expjkd/(1+rBackground*exp2jkd)*(1+rBackground)
        data['reflectionTE'] = np.abs(reflectionTE)
        data['reflectionTM'] = np.abs(reflectionTM)
        data['transmissionTE'] = np.abs(transmissionTE)
        data['transmissionTM'] = np.abs(transmissionTM)
        return data
    def _get_dataFrequency(self):
        epsilonSlab = self.slab.epsilonReal - 1j * self.slab.epsilonImage
        muSlab = self.slab.muReal - 1j * self.slab.muImage
        costheta = np.cos(self.incidentAngle * np.pi / 180)
        sintheta = np.sin(self.incidentAngle * np.pi / 180)
        kSlab = np.sqrt(epsilonSlab * muSlab - sintheta ** 2)
        zSlab = costheta / kSlab * muSlab
        ySlab = costheta / kSlab * epsilonSlab
        expjkd = np.exp(-2j * np.pi * self.frequencyRange * self.thickness / 300 * kSlab)
        exp2jkd = expjkd ** 2
        data={}
        match self.backgroundType:
            case '自由空间':
                r = (zSlab - 1) / (zSlab + 1)
                reflectionTE=(1 - exp2jkd) * r / (1 - exp2jkd * r ** 2)
                transmissionTE=(1 - r ** 2) * expjkd / (1 - exp2jkd * r ** 2)
                r = (ySlab - 1) / (ySlab + 1)
                reflectionTM=(1 - exp2jkd) * r / (1 - exp2jkd * r ** 2)
                transmissionTM=(1 - r ** 2) * expjkd / (1 - exp2jkd * r ** 2)
            case '导体':
                cosjkd = np.cos(-2j * np.pi * self.frequencyRange * self.thickness / 300 * kSlab)
                sinjkd = np.sin(-2j * np.pi * self.frequencyRange * self.thickness / 300 * kSlab)
                reflectionTE=(zSlab*1j*sinjkd-cosjkd)/(zSlab*1j*sinjkd+cosjkd)
                transmissionTE=np.zeros_like(reflectionTE)
                reflectionTM = (ySlab*cosjkd - 1j*sinjkd) / (ySlab*cosjkd + 1j*sinjkd)
                transmissionTM=np.zeros_like(reflectionTM)
            case '介质':
                epsilonBackground = self.background.epsilonReal - 1j * self.background.epsilonImage
                muBackground = self.background.muReal - 1j * self.background.muImage
                kBackground = np.sqrt(epsilonBackground * muBackground - sintheta ** 2)
                zBackground = kSlab/kBackground * muBackground/muSlab
                rBackground=(zBackground-1)/(zBackground+1)
                r=rBackground*exp2jkd
                zSlab*=(1+r)/(1-r)
                reflectionTE=(zSlab-1)/(zSlab+1)
                transmissionTE=(1+r)*expjkd/(1+rBackground*exp2jkd)*(1+rBackground)
                yBackground = kSlab/kBackground * epsilonBackground/epsilonSlab
                rBackground=(yBackground-1)/(yBackground+1)
                r=rBackground*exp2jkd
                ySlab*=(1+r)/(1-r)
                reflectionTM=(ySlab-1)/(ySlab+1)
                transmissionTM=(1+r)*expjkd/(1+rBackground*exp2jkd)*(1+rBackground)
        data['reflectionTE'] = np.abs(reflectionTE)
        data['reflectionTM'] = np.abs(reflectionTM)
        data['transmissionTE'] = np.abs(transmissionTE)
        data['transmissionTM'] = np.abs(transmissionTM)
        return data
    @observe("dataIncidentAngle")
    def _update_plotIncidentAngle(self, event):
        self.plotIncidentAngle.data.update_data(
            reflectionTE=self.dataIncidentAngle['reflectionTE'],
            reflectionTM=self.dataIncidentAngle['reflectionTM'],
            transmissionTE=self.dataIncidentAngle['transmissionTE'],
            transmissionTM=self.dataIncidentAngle['transmissionTM'],
        )
    @observe("dataFrequency")
    def _update_plotFrequency(self, event):
        self.plotFrequency.data.update_data(
            reflectionTE=self.dataFrequency['reflectionTE'],
            reflectionTM=self.dataFrequency['reflectionTM'],
            transmissionTE=self.dataFrequency['transmissionTE'],
            transmissionTM=self.dataFrequency['transmissionTM'],
        )
    traits_view=View(
        Group(
            UItem(
            "plotIncidentAngle",
            editor=ComponentEditor(),
        )),
        Item('frequency',label='频率/GHz'),
        Group(UItem(
            "plotFrequency",
            editor=ComponentEditor(),
            resizable=True
        )),
        Item('incidentAngle',label='入射角/°'),
        Item('thickness',label='厚度/mm'),
        HGroup(Group(UItem('slab'),label='介质板',style='custom',show_border=True),
                Group(UItem('background',enabled_when='backgroundType=="介质"'),label='底板',style='custom',show_border=True),
               show_border=True,
               ),
        Item('backgroundType',label='底板类型',style='custom'),
        width=1400,
        height=1000,
    )
class Absorber(HasTraits):
    epsilon=Complex(4-1j)
    mu=Complex(2-1j)
    thickness=Float(2)
    traits_view=View(HGroup(
        Item('epsilon',label='介电常数'),
        Item('mu',label='磁导率'),
        show_border=True,
    ))
table_editor = TableEditor(
    columns=[
        ObjectColumn(name='epsilon',label='介电常数',width=.3),
        ObjectColumn(name='mu',label='磁导率',width=.3),
        ObjectColumn(name='thickness',label='厚度/mm',width=.3),
    ],
    deletable=True,
    sortable=False,
    reorderable=True,
    show_toolbar=True,
    row_factory=Absorber,
)
class Ram(HasTraits):
    incidentAngleRange = np.arange(0,90.5,.5)
    frequencyRange = np.arange(0,100.1,.1)
    incidentAngle = Range(low=0, high=90., value=0.)# unit deg
    frequency = Range(low=0, high=100.0, value=2.0)# unit GHz
    plotIncidentAngle = Instance(Plot)
    plotFrequency = Instance(Plot)
    background=Instance(Absorber,())
    backgroundType=Enum('自由空间','导体','介质')
    costheta = np.cos(incidentAngleRange * np.pi / 180)
    sintheta = np.sin(incidentAngleRange * np.pi / 180)
    dataIncidentAngle = Property(Dict, observe=['absorbers','frequency','absorbers.items.*','background.*','backgroundType',])
    dataFrequency = Property(Dict, observe=['absorbers','incidentAngle','absorbers.items.*','background.*','backgroundType',])
    absorbers = List(Absorber,[
        Absorber(epsilon=3-1j,mu=2-1j),
        Absorber(epsilon=4-2j,mu=3-2j),
        Absorber(epsilon=5-2.5j,mu=4-3j),
        Absorber(epsilon=6-3j,mu=5-4j),
    ])
    def __init__(self):
        super().__init__()
    def _plotIncidentAngle_default(self):
        plot = Plot(ArrayPlotData(
            incidentAngleRange=self.incidentAngleRange,
            reflectionTE=self.dataIncidentAngle['reflectionTE'],
            reflectionTM=self.dataIncidentAngle['reflectionTM'],
            transmissionTE=self.dataIncidentAngle['transmissionTE'],
            transmissionTM=self.dataIncidentAngle['transmissionTM'],
                                      ))
        plot.title = 'Reflection and Transmission'
        plot.x_axis.title = "Incident Angle / deg"
        plot.y_axis.title = "Reflection and Transmission"
        plot.range2d.set_bounds((0, 0), (90, 2))
        plot.plot(("incidentAngleRange", "reflectionTE"),name='Reflection TE',color=palette11[0])
        plot.plot(("incidentAngleRange", "reflectionTM"),name='Reflection TM',color=palette11[1])
        plot.plot(("incidentAngleRange", "transmissionTE"),name='Transmission TE',color=palette11[2])
        plot.plot(("incidentAngleRange", "transmissionTM"),name='Transmission TM',color=palette11[3])
        legend = Legend()
        legend.plots = plot.plots
        plot.overlays.append(legend)
        return plot
    def _plotFrequency_default(self):
        plot = Plot(ArrayPlotData(
            frequencyRange=self.frequencyRange,
            reflectionTE=self.dataFrequency['reflectionTE'],
            reflectionTM=self.dataFrequency['reflectionTM'],
            transmissionTE=self.dataFrequency['transmissionTE'],
            transmissionTM=self.dataFrequency['transmissionTM'],
                                      ))
        plot.title = 'Reflection and Transmission'
        plot.x_axis.title = "Frequency / GHz"
        plot.y_axis.title = "Reflection and Transmission"
        plot.range2d.set_bounds((0, 0), (90, 2))
        plot.plot(("frequencyRange", "reflectionTE"),name='Reflection TE',color=palette11[0])
        plot.plot(("frequencyRange", "reflectionTM"),name='Reflection TM',color=palette11[1])
        plot.plot(("frequencyRange", "transmissionTE"),name='Transmission TE',color=palette11[2])
        plot.plot(("frequencyRange", "transmissionTM"),name='Transmission TM',color=palette11[3])
        legend = Legend()
        legend.plots = plot.plots
        plot.overlays.append(legend)
        return plot
    def _get_dataIncidentAngle(self):
        match self.backgroundType:
            case '自由空间':
                k = self.costheta
                z=np.array(1/k,dtype=complex)
                y=np.array(1/k,dtype=complex)
            case '导体':
                z = complex(0)
                y = complex(1e100)
            case '介质':
                k = np.sqrt(self.background.epsilon * self.background.mu - self.sintheta ** 2)
                z=np.array(self.background.mu/k,dtype=complex)
                y=np.array(self.background.epsilon/k,dtype=complex)
        for a in reversed(self.absorbers):
            k = np.sqrt(a.epsilon * a.mu - self.sintheta ** 2)
            z*=k/a.mu
            y*=k/a.epsilon
            exp2jkd = np.exp(-4j * np.pi * self.frequency * a.thickness / 300 * k)
            rTE=(z-1)/(z+1)*exp2jkd
            rTM=(y-1)/(y+1)*exp2jkd
            z=(1+rTE)/(1-rTE)
            y=(1+rTM)/(1-rTM)
        k = self.costheta
        z *= k
        y *= k
        reflectionTE=np.abs((z-1)/(z+1))
        reflectionTM=np.abs((y-1)/(y+1))
        transmissionTE=np.abs(2*z/(z+1))#待修改完善
        transmissionTM=np.abs(2*y/(y+1))#待修改完善
        data={}
        data['reflectionTE'] = np.abs(reflectionTE)
        data['reflectionTM'] = np.abs(reflectionTM)
        data['transmissionTE'] = np.abs(transmissionTE)
        data['transmissionTM'] = np.abs(transmissionTM)
        return data
    def _get_dataFrequency(self):
        costheta = np.cos(self.incidentAngle * np.pi / 180)
        sintheta = np.sin(self.incidentAngle * np.pi / 180)
        match self.backgroundType:
            case '自由空间':
                k = costheta
                z=complex(1/k)
                y=complex(1/k)
            case '导体':
                z = complex(0)
                y = complex(1e100)
            case '介质':
                k = np.sqrt(self.background.epsilon * self.background.mu - sintheta ** 2)
                z=np.array(self.background.mu/k,dtype=complex)
                y=np.array(self.background.epsilon/k,dtype=complex)
        for a in reversed(self.absorbers):
            k = np.sqrt(a.epsilon * a.mu - sintheta ** 2)
            z*=k/a.mu
            y*=k/a.epsilon
            exp2jkd = np.exp(-4j * np.pi * self.frequencyRange * a.thickness / 300 * k)
            rTE=(z-1)/(z+1)*exp2jkd
            rTM=(y-1)/(y+1)*exp2jkd
            z=(1+rTE)/(1-rTE)
            y=(1+rTM)/(1-rTM)
        k = costheta
        z *= k
        y *= k
        reflectionTE=np.abs((z-1)/(z+1))
        reflectionTM=np.abs((y-1)/(y+1))
        transmissionTE=np.abs(2*z/(z+1))#待修改完善
        transmissionTM=np.abs(2*y/(y+1))#待修改完善
        data={}
        data['reflectionTE'] = np.abs(reflectionTE)
        data['reflectionTM'] = np.abs(reflectionTM)
        data['transmissionTE'] = np.abs(transmissionTE)
        data['transmissionTM'] = np.abs(transmissionTM)
        return data
    @observe("dataIncidentAngle")
    def _update_plot(self, event):
        self.plotIncidentAngle.data.update_data(
            reflectionTE=self.dataIncidentAngle['reflectionTE'],
            reflectionTM=self.dataIncidentAngle['reflectionTM'],
            transmissionTE=self.dataIncidentAngle['transmissionTE'],
            transmissionTM=self.dataIncidentAngle['transmissionTM'],
        )
    @observe("dataFrequency")
    def _update_plotFrequency(self, event):
        self.plotFrequency.data.update_data(
            reflectionTE=self.dataFrequency['reflectionTE'],
            reflectionTM=self.dataFrequency['reflectionTM'],
            transmissionTE=self.dataFrequency['transmissionTE'],
            transmissionTM=self.dataFrequency['transmissionTM'],
        )
    straits_view=View(
        Group(UItem(
            "plotIncidentAngle",
            editor=ComponentEditor(),
            resizable=True
        )),
        Item('frequency', label='频率/GHz'),
        Group(UItem(
            "plotFrequency",
            editor=ComponentEditor(),
            resizable=True
        )),
        Item('incidentAngle', label='入射角/°'),
        HGroup(Item('backgroundType',label='底板类型',style='custom'),
                Item('background',enabled_when='backgroundType=="介质"',label='底板',style='custom'),
                show_border=True
            ),
        Item('absorbers', editor=table_editor,height=200,label='吸波材料'),
        resizable=True,
        width=1200,
        height=800,
    )
class Cylinder(HasTraits):
    scatteringAngleRange = np.arange(0, 360, .5)
    kaRange = np.arange(.1, 20.1, .2)
    scatteringAngle = Range(low=0, high=360.1, value=0.)# unit deg
    ka = Range(low=0.1, high=20.0, value=2.0)# unit GHz
    plotScatteringAngle = Instance(Plot)
    plotKa = Instance(Plot)
    dataScatteringAngle = Property(Dict, observe=['ka'])
    dataKa = Property(Dict, observe=['scatteringAngle'])
    def _plotScatteringAngle_default(self):
        plot = Plot(ArrayPlotData(
            scatteringAngleRange=self.scatteringAngleRange,
            rcsTM=self.dataScatteringAngle['TM'],
            rcsTE=self.dataScatteringAngle['TE'],
                                      ))
        plot.title = 'RCS'
        plot.x_axis.title = "Bistatic Angle / deg"
        plot.y_axis.title = "RCS / dBm"
        plot.plot(("scatteringAngleRange", "rcsTM"),name='TM',color=palette11[0])
        plot.plot(("scatteringAngleRange", "rcsTE"),name='TE',color=palette11[1])
        legend = Legend()
        legend.plots = plot.plots
        plot.overlays.append(legend)
        return plot
    def _plotKa_default(self):
        plot = Plot(ArrayPlotData(
            kaRange=self.kaRange,
            rcsTM=self.dataKa['TM'],
            rcsTE=self.dataKa['TE'],
                                      ))
        plot.title = 'RCS'
        plot.x_axis.title = "ka"
        plot.y_axis.title = "RCS /dBm"
        plot.range2d.set_bounds((0, -30), (20, 10))
        plot.plot(("kaRange", "rcsTM"),name='TM',color=palette11[0])
        plot.plot(("kaRange", "rcsTE"),name='TE',color=palette11[1])
        legend = Legend()
        legend.plots = plot.plots
        plot.overlays.append(legend)
        return plot
    def _get_dataScatteringAngle(self):
        n=np.arange(-50,51)
        jn=sc.jv(n,self.ka)
        hn=sc.hankel2(n,self.ka)
        jn1=sc.jv(n-1,self.ka)
        hn1=sc.hankel2(n-1,self.ka)
        tm=(-1.)**n*jn/hn
        te=(-1.)**n*(self.ka*jn1-n*jn)/(self.ka*hn1-n*hn)
        expValue=np.exp(1j * np.outer(n, self.scatteringAngleRange) * np.pi / 180)
        tm=-2*np.exp(1j*np.pi/4)/np.sqrt(np.pi*self.ka)*tm@expValue
        te=-2*np.exp(1j*np.pi/4)/np.sqrt(np.pi*self.ka)*te@expValue
        data={}
        data['TE'] =10*np.log10(np.abs(tm))
        data['TM'] =10*np.log10(np.abs(te))
        return data
    def _get_dataKa(self):
        nRange=np.arange(-50,51)
        tm=np.zeros_like(self.kaRange,dtype=complex)
        te=np.zeros_like(self.kaRange,dtype=complex)
        n,ka=np.meshgrid(nRange,self.kaRange)
        jn=sc.jv(n,ka)
        hn=sc.hankel2(n,ka)
        jn1=sc.jv(n-1,ka)
        hn1=sc.hankel2(n-1,ka)
        tmTmp=(-1.)**n*jn/hn
        teTmp=(-1.)**n*(ka*jn1-n*jn)/(ka*hn1-n*hn)
        expValue=np.exp(1j * nRange * self.scatteringAngle * np.pi / 180)
        factor=-2 * np.exp(1j * np.pi / 4) / np.sqrt(np.pi * ka)
        tm=factor*tmTmp@expValue#乘法优先级高于矩阵乘法
        te=factor*teTmp@expValue
        data={}
        data['TE'] =10*np.log10(np.abs(tm))
        data['TM'] =10*np.log10(np.abs(te))
        return data

    def _dataScatteringAngle_changed(self):
        self.plotScatteringAngle.data.update_data(
            rcsTM=self.dataScatteringAngle['TM'],
            rcsTE=self.dataScatteringAngle['TE'],
        )
    @observe("dataKa")
    def _update_plotKa(self, event):
        self.plotKa.data.update_data(
            rcsTM=self.dataKa['TM'],
            rcsTE=self.dataKa['TE'],
        )
    straits_view=View(
        Group(UItem(
            "plotScatteringAngle",
            editor=ComponentEditor(),
            resizable=True
        )),
        Item('ka', label='ka'),
        Group(UItem(
            "plotKa",
            editor=ComponentEditor(),
            resizable=True
        )),
        Item('scatteringAngle',label='双站角/°'),
        resizable=True,
        width=1200,
        height=800,
    )
class Form(HasTraits):
    monoInteface = Instance(MonoInteface,())
    myslab = Instance(Slab,())
    ram = Instance(Ram,())
    cylinder = Instance(Cylinder,())
    traits_view=View(
        Tabbed(
            UItem('monoInteface',style='custom',label='单层反射面'),
            UItem('myslab',style='custom',label='介质板'),
            UItem('ram',style='custom',label='多层吸波材料'),
            UItem('cylinder',style='custom',label='圆柱RCS'),
        ),
    title='材料计算',
    width=1200,
    height=800,
    resizable=True,
    )
if __name__ == '__main__':
    form=Form()
    form.configure_traits()
